package com.fractalist.man.base;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

/**
 * 对JdbcTemplate的简单封装
 * 
 * @author samoin
 * @since 2013-11-20
 */
public class BaseJdbcTemplate {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	/**
	 * 调用jdbctemplate的update方法，直接返回受影响的结果条数
	 * 
	 * @param sql
	 * @return
	 */
	public Integer updateBase(String sql) {
		SqlUtils.print(sql);
		return jdbcTemplate.update(sql);
	}

	/**
	 * 更新数据
	 * 
	 * @param sql
	 * @return 本次更新是否成功
	 */
	public Boolean update(String sql) {
		boolean flag = false;
		try {
			SqlUtils.print(sql);
			flag = jdbcTemplate.update(sql) > 0;
		} catch (Exception e) {
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}

	/**
	 * 插入数据
	 * 
	 * @param sql
	 * @return 插入后的id
	 */
	public Long add(String sql) {
		SqlUtils.print(sql);
		return insertWithReturnId(sql);
	}

	/**
	 * 查询一条记录
	 * 
	 * @param sql
	 * @return
	 */
	public Map<String, Object> queryOneRow(String sql) {
		Map<String, Object> result = null;
		SqlUtils.print(sql);
		List<Map<String, Object>> list = queryList(sql);
		if (list != null && list.size() > 0) {
			result = list.get(0);
		}
		return result;
	}

	/**
	 * 查询一组记录
	 * 
	 * @param sql
	 * @return
	 */
	public List<Map<String, Object>> queryList(String sql) {
		List<Map<String, Object>> list = null;
		try {
			SqlUtils.print(sql);
			list = jdbcTemplate.queryForList(sql);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 通过batch的方式，一次批量提交sql语句并执行 F
	 * 
	 * @param sql
	 * @return
	 */
	public int[] batchUpdate(String[] sql) {
		int[] updateArr = null;
		try {
			SqlUtils.print(sql);
			updateArr = jdbcTemplate.batchUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return updateArr;
	}

	/**
	 * 执行一条sql语句，不管是否会执行成功
	 * 
	 * @param sql
	 */
	public void excute(String sql) {
		SqlUtils.print(sql);
		jdbcTemplate.execute(sql);
	}

	/**
	 * 对插入的简单封装 ,请自己去封装sql语句，否则对PreparedStatement的处理很麻烦<br/>
	 * <font color=red><b>注：从网上找的，对并发的测试不确定，后续做完以后可以考虑</b></font><br/>
	 * 
	 * @param sql
	 * @param jdbcTemplate
	 * @return 插入的记录的id，前提该表的id为自增
	 */
	protected Long insertWithReturnId(final String sql) {
		KeyHolder holder = new GeneratedKeyHolder();
		try {
			PreparedStatementCreator psc = new PreparedStatementCreator() {
				public PreparedStatement createPreparedStatement(Connection con)
						throws SQLException {
					PreparedStatement ps = con.prepareStatement(sql,
							Statement.RETURN_GENERATED_KEYS);
					return ps;
				}
			};
			jdbcTemplate.update(psc, holder);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(sql);
			return 0L;
		}
		if (holder.getKey() != null) {
			return holder.getKey().longValue();
		} else {
			return -1L;
		}
	}
}
